<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  
  <title>OpenFOAM 中的单相流湍流模型之一 | Giskard&#39;s CFD Learning Tricks</title>
  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
  <meta name="description" content="相信有不少 OpenFOAM 用户有添加湍流模型的需求，我自己最早用 OpenFOAM 完成的一项工作就是在其中添加了一些单相流的湍流模型，并进行了一些计算。这里将我对单相湍流模型代码框架的理解记录下来，供大家参考。本系列将包含三篇，第一篇介绍湍流模型类的继承派生关系，第二篇具体分析几个 OpenFOAM 中带的湍流模型，并给出修改或增加新模型的方法，第三篇分析湍流模型的运行时选择机制（Run T">
<meta property="og:type" content="article">
<meta property="og:title" content="OpenFOAM 中的单相流湍流模型之一">
<meta property="og:url" content="http://xiaopingqiu.github.io/2015/11/25/OpenFOAM-singlePhase-turbulenceModel/index.html">
<meta property="og:site_name" content="Giskard's CFD Learning Tricks">
<meta property="og:description" content="相信有不少 OpenFOAM 用户有添加湍流模型的需求，我自己最早用 OpenFOAM 完成的一项工作就是在其中添加了一些单相流的湍流模型，并进行了一些计算。这里将我对单相湍流模型代码框架的理解记录下来，供大家参考。本系列将包含三篇，第一篇介绍湍流模型类的继承派生关系，第二篇具体分析几个 OpenFOAM 中带的湍流模型，并给出修改或增加新模型的方法，第三篇分析湍流模型的运行时选择机制（Run T">
<meta property="og:image" content="/image/turbulenceModel/RAS_LES.png">
<meta property="og:image" content="/image/turbulenceModel/RAS.png">
<meta property="og:image" content="/image/turbulenceModel/LES.png">
<meta property="og:image" content="/image/turbulenceModel/call.png">
<meta name="twitter:card" content="summary">
<meta name="twitter:title" content="OpenFOAM 中的单相流湍流模型之一">
<meta name="twitter:description" content="相信有不少 OpenFOAM 用户有添加湍流模型的需求，我自己最早用 OpenFOAM 完成的一项工作就是在其中添加了一些单相流的湍流模型，并进行了一些计算。这里将我对单相湍流模型代码框架的理解记录下来，供大家参考。本系列将包含三篇，第一篇介绍湍流模型类的继承派生关系，第二篇具体分析几个 OpenFOAM 中带的湍流模型，并给出修改或增加新模型的方法，第三篇分析湍流模型的运行时选择机制（Run T">
  
  
    <link rel="icon" href="/favicon.png">
  
  <link href="//fonts.googleapis.com/css?family=Source+Code+Pro" rel="stylesheet" type="text/css">
  <link rel="stylesheet" href="/css/style.css" type="text/css">
  
<!-- Google Analytics -->
<script type="text/javascript">
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');

##ga('create', '[object Object]', 'auto');
ga('create', 'UA-62501686-1', 'auto');
ga('send', 'pageview');

</script>
<!-- End Google Analytics -->


</head>
<body>
  <div id="container">
    <div id="wrap">
      <header id="header">
  <div id="banner"></div>
  <div id="header-outer" class="outer">
    <div id="header-title" class="inner">
      <h1 id="logo-wrap">
        <a href="/" id="logo">Giskard&#39;s CFD Learning Tricks</a>
      </h1>
      
        <h2 id="subtitle-wrap">
          <a href="/" id="subtitle">CFD and Scientific Computing</a>
        </h2>
      
    </div>
    <div id="header-inner" class="inner">
      <nav id="main-nav">
        <a id="main-nav-toggle" class="nav-icon"></a>
        
          <a class="main-nav-link" href="/">Home</a>
        
          <a class="main-nav-link" href="/archives">Archives</a>
        
          <a class="main-nav-link" href="/atom.xml">Rss</a>
        
          <a class="main-nav-link" href="/about">About</a>
        
      </nav>
      <nav id="sub-nav">
        
        <a id="nav-search-btn" class="nav-icon" title="Search"></a>
      </nav>
      <div id="search-form-wrap">
        <form action="//google.com/search" method="get" accept-charset="UTF-8" class="search-form"><input type="search" name="q" results="0" class="search-form-input" placeholder="Search"><button type="submit" class="search-form-submit">&#xF002;</button><input type="hidden" name="q" value="site:http://xiaopingqiu.github.io"></form>
      </div>
    </div>
  </div>
</header>

      <div class="outer">
        <section id="main"><article id="post-OpenFOAM-singlePhase-turbulenceModel" class="article article-type-post" itemscope itemprop="blogPost">
  <div class="article-meta">
    <a href="/2015/11/25/OpenFOAM-singlePhase-turbulenceModel/" class="article-date">
  <time datetime="2015-11-25T11:13:58.000Z" itemprop="datePublished">2015-11-25</time>
</a>
    
  <div class="article-category">
    <a class="article-category-link" href="/categories/OpenFOAM/">OpenFOAM</a>
  </div>

  </div>
  <div class="article-inner">
    
    
      <header class="article-header">
        
  
    <h1 class="article-title" itemprop="name">
      OpenFOAM 中的单相流湍流模型之一
    </h1>
  

      </header>
    
    <div class="article-entry" itemprop="articleBody">
      
        <p>相信有不少 OpenFOAM 用户有添加湍流模型的需求，我自己最早用 OpenFOAM 完成的一项工作就是在其中添加了一些单相流的湍流模型，并进行了一些计算。这里将我对单相湍流模型代码框架的理解记录下来，供大家参考。本系列将包含三篇，第一篇介绍湍流模型类的继承派生关系，第二篇具体分析几个 OpenFOAM 中带的湍流模型，并给出修改或增加新模型的方法，第三篇分析湍流模型的运行时选择机制（Run Time Selection）的原理。</p>
<a id="more"></a>
<h4 id="1-_湍流模型类的继承派生关系">1. 湍流模型类的继承派生关系</h4><p>这一部分是最简单的，只要有一点<code>C++</code>的知识，看一下湍流模型的代码头文件的类声明部分，就能理解。OpenFOAM 里的单相湍流模型包含两大类，<code>RAS</code> 和 <code>LES</code>，下面将分别分析。</p>
<p>OpenFOAM 单相流湍流模型的代码在 <code>src/turbulenceModels</code> 目录下，目录结构如下：<br><figure class="highlight nginx"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="title">Allwmake</span>  compressible  derivedFvPatchFields  incompressible  LES</span><br></pre></td></tr></table></figure></p>
<p>其中， <code>compressible</code> 和 <code>incompressible</code> 分别是可压缩和不可压缩湍流模型的代码， <code>derivedFvPatchFields</code> 是两个湍流相关的边界条件的代码， <code>LES</code> 是大涡模拟的两个相关的类（ <code>LESdeltas</code> 和 <code>LESfilters</code> ），具体在后面会介绍。这里我主要关心不可压缩湍流模型。<br>进入<code>incompressible</code>，目录结构为：<br><figure class="highlight elixir"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="variable">$ </span> cd  incompressible</span><br><span class="line"><span class="variable">$ </span> ls</span><br><span class="line"><span class="constant">Allwmake </span> <span class="constant">LES </span> <span class="constant">RAS </span> turbulenceModel</span><br></pre></td></tr></table></figure></p>
<p>这里， 目录<code>turbulenceModel</code> 里是基类 <code>turbulenceModel</code> 相关的代码， <code>RAS</code> 和 <code>LES</code> ，顾名思义，分别是雷诺时均和大涡模拟湍流模型的代码。</p>
<h5 id="1-1_基类_turbulenceModel">1.1 基类 <code>turbulenceModel</code></h5><p>首先看基类 <code>turbulenceModel</code> ，这里我挑着我觉得重要的部分代码列出来：</p>
<p>先看头文件 turbulenceModel.H：<br><figure class="highlight cs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br><span class="line">143</span><br><span class="line">144</span><br><span class="line">145</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">namespace</span> <span class="title">Foam</span></span><br><span class="line">&#123;</span><br><span class="line"></span><br><span class="line"><span class="comment">// incompressible 命名空间，注意这个是很重要的，作用是将类隔离开。比如，可压和不可压都有kEpsilon模型，这两个模型的类名是一样的。要区分这两个类，靠的就是这个命名空间。可压的是 compressible::kEpsilon, 而不可压的则是 incompressible::kEpsilon</span></span><br><span class="line"><span class="keyword">namespace</span> <span class="title">incompressible</span> </span><br><span class="line">&#123;</span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title">turbulenceModel</span> <span class="comment">//定义一个 turbulenceModel 类，继承自 regIOobject 类</span></span><br><span class="line">:</span><br><span class="line">    <span class="title">public</span> <span class="title">regIOobject</span></span><br><span class="line">&#123;</span><br><span class="line"></span><br><span class="line"><span class="keyword">protected</span>:</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 数据成员</span></span><br><span class="line">        <span class="keyword">const</span> Time&amp; runTime_;</span><br><span class="line">        <span class="keyword">const</span> fvMesh&amp; mesh_;</span><br><span class="line"></span><br><span class="line">        <span class="keyword">const</span> volVectorField&amp; U_;</span><br><span class="line">        <span class="keyword">const</span> surfaceScalarField&amp; phi_;</span><br><span class="line"></span><br><span class="line">        transportModel&amp; transportModel_; <span class="comment">// 输运模型，涉及到分子粘度的设置</span></span><br><span class="line"></span><br><span class="line">        <span class="comment">//- Near wall distance boundary field</span></span><br><span class="line">        nearWallDist y_;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line"></span><br><span class="line">    <span class="comment">//- Runtime type information</span></span><br><span class="line">    TypeName(<span class="string">"turbulenceModel"</span>);</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">    <span class="comment">// Declare run-time New selection table 这个跟运行时选择有关，具体以后会涉及</span></span><br><span class="line"></span><br><span class="line">        declareRunTimeNewSelectionTable</span><br><span class="line">        (</span><br><span class="line">            autoPtr,</span><br><span class="line">            turbulenceModel,</span><br><span class="line">            turbulenceModel,</span><br><span class="line">            (</span><br><span class="line">                <span class="keyword">const</span> volVectorField&amp; U,</span><br><span class="line">                <span class="keyword">const</span> surfaceScalarField&amp; phi,</span><br><span class="line">                transportModel&amp; transport,</span><br><span class="line">                <span class="keyword">const</span> word&amp; turbulenceModelName</span><br><span class="line">            ),</span><br><span class="line">            (U, phi, transport, turbulenceModelName)</span><br><span class="line">        );</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">    <span class="comment">// Constructors  构造函数</span></span><br><span class="line"></span><br><span class="line">        <span class="comment">//- Construct from components</span></span><br><span class="line">        turbulenceModel</span><br><span class="line">        (</span><br><span class="line">            <span class="keyword">const</span> volVectorField&amp; U,</span><br><span class="line">            <span class="keyword">const</span> surfaceScalarField&amp; phi,</span><br><span class="line">            transportModel&amp; transport,</span><br><span class="line">            <span class="keyword">const</span> word&amp; turbulenceModelName = typeName</span><br><span class="line">        );</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">    <span class="comment">// Selectors // 这个也是跟运行时选择机制有关，涉及到具体湍流模型的选择过程</span></span><br><span class="line">        <span class="comment">//- Return a reference to the selected turbulence model</span></span><br><span class="line">        <span class="function"><span class="keyword">static</span> autoPtr&lt;turbulenceModel&gt; <span class="title">New</span></span><br><span class="line">        <span class="params">(</span><br><span class="line">            <span class="keyword">const</span> volVectorField&amp; U,</span><br><span class="line">            <span class="keyword">const</span> surfaceScalarField&amp; phi,</span><br><span class="line">            transportModel&amp; transport,</span><br><span class="line">            <span class="keyword">const</span> word&amp; turbulenceModelName = typeName</span><br><span class="line">        )</span></span>;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">    <span class="comment">// Member Functions</span></span><br><span class="line"></span><br><span class="line">        <span class="comment">//- Const access to the coefficients dictionary</span></span><br><span class="line">        <span class="keyword">virtual</span> <span class="keyword">const</span> dictionary&amp; coeffDict() <span class="keyword">const</span> = <span class="number">0</span>;</span><br><span class="line"></span><br><span class="line">        <span class="comment">//- Helper function to return the nam eof the turbulence G field</span></span><br><span class="line">        <span class="function">inline word <span class="title">GName</span><span class="params">()</span> <span class="keyword">const</span></span><br><span class="line">        </span>&#123;</span><br><span class="line">            <span class="keyword">return</span> word(type() + <span class="string">":G"</span>);</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">        <span class="comment">//- Access function to velocity field</span></span><br><span class="line">        inline <span class="keyword">const</span> volVectorField&amp; U() <span class="keyword">const</span></span><br><span class="line">        &#123;</span><br><span class="line">            <span class="keyword">return</span> U_;</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">        <span class="comment">//- Access function to flux field</span></span><br><span class="line">        inline <span class="keyword">const</span> surfaceScalarField&amp; phi() <span class="keyword">const</span></span><br><span class="line">        &#123;</span><br><span class="line">            <span class="keyword">return</span> phi_;</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">        <span class="comment">//- Access function to incompressible transport model</span></span><br><span class="line">        inline transportModel&amp; transport() <span class="keyword">const</span></span><br><span class="line">        &#123;</span><br><span class="line">            <span class="keyword">return</span> transportModel_;</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">        <span class="comment">//- Return the near wall distances</span></span><br><span class="line">        <span class="keyword">const</span> nearWallDist&amp; y() <span class="keyword">const</span></span><br><span class="line">        &#123;</span><br><span class="line">            <span class="keyword">return</span> y_;</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">        <span class="comment">//- Return the laminar viscosity</span></span><br><span class="line">	<span class="comment">// 分子粘度，注意这里的返回值是输运模型类对象的 nu 函数的返回值。</span></span><br><span class="line">	<span class="comment">// 具体来说，如果是牛顿流体，那么这个返回值就是我们在transportProperties里设置的粘度；</span></span><br><span class="line">	<span class="comment">// 如果是非牛顿流体，那么粘度是根据具体的非牛顿流体模型计算得到的。</span></span><br><span class="line">        <span class="function">inline tmp&lt;volScalarField&gt; <span class="title">nu</span><span class="params">()</span> <span class="keyword">const</span> </span><br><span class="line">        </span>&#123;</span><br><span class="line">            <span class="keyword">return</span> transportModel_.nu();</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 以下形如 "virtual <span class="label">xxxx () const = 0" 的函数，都是纯虚函数，这是很重要的一部分。</span></span></span><br><span class="line">    <span class="comment">// 当一个类中有纯虚函数时，这个类就被称作抽象类，抽象类本身不能建立对象，一般都是作为接口类来使用。</span></span><br><span class="line">    <span class="comment">// 这里的turbulenceModel类就是接口类，“接口类”三个字的具体含义后面会解释。</span></span><br><span class="line">        <span class="comment">//- Return the turbulence viscosity</span></span><br><span class="line">        <span class="function"><span class="keyword">virtual</span> tmp&lt;volScalarField&gt; <span class="title">nut</span><span class="params">()</span> <span class="keyword">const</span> </span>= <span class="number">0</span>;</span><br><span class="line">        <span class="comment">//- Return the effective viscosity</span></span><br><span class="line">        <span class="function"><span class="keyword">virtual</span> tmp&lt;volScalarField&gt; <span class="title">nuEff</span><span class="params">()</span> <span class="keyword">const</span> </span>= <span class="number">0</span>;</span><br><span class="line">        <span class="comment">//- Return the turbulence kinetic energy</span></span><br><span class="line">        <span class="function"><span class="keyword">virtual</span> tmp&lt;volScalarField&gt; <span class="title">k</span><span class="params">()</span> <span class="keyword">const</span> </span>= <span class="number">0</span>;</span><br><span class="line">        <span class="comment">//- Return the turbulence kinetic energy dissipation rate</span></span><br><span class="line">        <span class="function"><span class="keyword">virtual</span> tmp&lt;volScalarField&gt; <span class="title">epsilon</span><span class="params">()</span> <span class="keyword">const</span> </span>= <span class="number">0</span>;</span><br><span class="line">        <span class="comment">//- Return the Reynolds stress tensor</span></span><br><span class="line">        <span class="function"><span class="keyword">virtual</span> tmp&lt;volSymmTensorField&gt; <span class="title">R</span><span class="params">()</span> <span class="keyword">const</span> </span>= <span class="number">0</span>;</span><br><span class="line">        <span class="comment">//- Return the effective stress tensor including the laminar stress</span></span><br><span class="line">        <span class="function"><span class="keyword">virtual</span> tmp&lt;volSymmTensorField&gt; <span class="title">devReff</span><span class="params">()</span> <span class="keyword">const</span> </span>= <span class="number">0</span>;</span><br><span class="line">        <span class="comment">//- Return the source term for the momentum equation</span></span><br><span class="line">        <span class="function"><span class="keyword">virtual</span> tmp&lt;fvVectorMatrix&gt; <span class="title">divDevReff</span><span class="params">(volVectorField&amp; U)</span> <span class="keyword">const</span> </span>= <span class="number">0</span>;</span><br><span class="line">        <span class="comment">//- Return the source term for the momentum equation</span></span><br><span class="line">        <span class="function"><span class="keyword">virtual</span> tmp&lt;fvVectorMatrix&gt; <span class="title">divDevRhoReff</span></span><br><span class="line">        <span class="params">(</span><br><span class="line">            <span class="keyword">const</span> volScalarField&amp; rho,</span><br><span class="line">            volVectorField&amp; U</span><br><span class="line">        )</span> <span class="keyword">const</span> </span>= <span class="number">0</span>;</span><br><span class="line">        <span class="comment">//- Solve the turbulence equations and correct the turbulence viscosity</span></span><br><span class="line">        <span class="function"><span class="keyword">virtual</span> <span class="keyword">void</span> <span class="title">correct</span><span class="params">()</span> </span>= <span class="number">0</span>;</span><br><span class="line"></span><br><span class="line">        <span class="comment">//- Read LESProperties or RASProperties dictionary</span></span><br><span class="line">        <span class="function"><span class="keyword">virtual</span> <span class="keyword">bool</span> <span class="title">read</span><span class="params">()</span> </span>= <span class="number">0</span>;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure></p>
<p>再来看 turbulenceModel.C，重点关注构造函数和 New 函数<br><figure class="highlight gherkin"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br></pre></td><td class="code"><pre><span class="line">namespace Foam</span><br><span class="line">&#123;</span><br><span class="line">namespace incompressible</span><br><span class="line">&#123;</span><br><span class="line"></span><br><span class="line">// <span class="keyword">*</span> <span class="keyword">*</span> <span class="keyword">*</span> <span class="keyword">*</span> <span class="keyword">*</span> <span class="keyword">*</span> <span class="keyword">*</span> <span class="keyword">*</span> <span class="keyword">*</span> <span class="keyword">*</span> <span class="keyword">*</span> <span class="keyword">*</span> <span class="keyword">*</span> <span class="keyword">*</span> Static Data Members <span class="keyword">*</span> <span class="keyword">*</span> <span class="keyword">*</span> <span class="keyword">*</span> <span class="keyword">*</span> <span class="keyword">*</span> <span class="keyword">*</span> <span class="keyword">*</span> <span class="keyword">*</span> <span class="keyword">*</span> <span class="keyword">*</span> <span class="keyword">*</span> <span class="keyword">*</span> </span><br><span class="line"></span><br><span class="line">//这句与运行时选择机制有关，后面再说</span><br><span class="line">defineRunTimeSelectionTable(turbulenceModel, turbulenceModel);</span><br><span class="line"></span><br><span class="line">//构造函数的定义。构造函数包括四个参数，其中最后一个<span class="string">"turbulenceModelName"</span>是带缺省参数的，所以，只需要提供三个参数。</span><br><span class="line">turbulenceModel::turbulenceModel</span><br><span class="line">(</span><br><span class="line">    const volVectorField&amp; U,</span><br><span class="line">    const surfaceScalarField&amp; phi,</span><br><span class="line">    transportModel&amp; transport,</span><br><span class="line">    const word&amp; turbulenceModelName</span><br><span class="line">)</span><br><span class="line">//  这里往下一段叫做成员初始化列表，用于对当前类以及其基类成员进行初始化</span><br><span class="line">:</span><br><span class="line">    regIOobject</span><br><span class="line">    (</span><br><span class="line">        IOobject</span><br><span class="line">        (</span><br><span class="line">            turbulenceModelName,</span><br><span class="line">            U.time().constant(),</span><br><span class="line">            U.db(),</span><br><span class="line">            IOobject::NO_READ,</span><br><span class="line">            IOobject::NO_WRITE</span><br><span class="line">        )</span><br><span class="line">    ),</span><br><span class="line">    runTime_(U.time()),</span><br><span class="line">    mesh_(U.mesh()),</span><br><span class="line"></span><br><span class="line">    U_(U),</span><br><span class="line">    phi_(phi),</span><br><span class="line">    transportModel_(transport), // 输运模型从构造函数的参数中读取</span><br><span class="line">    y_(mesh_)</span><br><span class="line">&#123;&#125;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">// <span class="keyword">*</span> <span class="keyword">*</span> <span class="keyword">*</span> <span class="keyword">*</span> <span class="keyword">*</span> <span class="keyword">*</span> <span class="keyword">*</span> <span class="keyword">*</span> <span class="keyword">*</span> <span class="keyword">*</span> <span class="keyword">*</span> <span class="keyword">*</span> <span class="keyword">*</span> <span class="keyword">*</span> <span class="keyword">*</span> <span class="keyword">*</span> <span class="keyword">*</span> Selectors <span class="keyword">*</span> <span class="keyword">*</span> <span class="keyword">*</span> <span class="keyword">*</span> <span class="keyword">*</span> <span class="keyword">*</span> <span class="keyword">*</span> <span class="keyword">*</span> <span class="keyword">*</span> <span class="keyword">*</span> <span class="keyword">*</span> <span class="keyword">*</span> <span class="keyword">*</span> <span class="keyword">*</span> <span class="keyword">*</span> //</span><br><span class="line"></span><br><span class="line">这个函数，起着选择具体湍流模型的作用，后面我会结合求解器代码仔细说说这个函数。更详细的机制，将在结合运行时选择机制来解释。</span><br><span class="line">autoPtr<span class="variable">&lt;turbulenceModel&gt;</span> turbulenceModel::New</span><br><span class="line">(</span><br><span class="line">    const volVectorField&amp; U,</span><br><span class="line">    const surfaceScalarField&amp; phi,</span><br><span class="line">    transportModel&amp; transport,</span><br><span class="line">    const word&amp; turbulenceModelName</span><br><span class="line">)</span><br><span class="line">&#123;</span><br><span class="line">    </span><br><span class="line">    // 注意这里了，算例中的<span class="string">"turbulenceProperties"</span> 文件即由这段代码来读取。</span><br><span class="line">    // 需要从<span class="string">"turbulenceProperties"</span> 文件中查找一个关键字<span class="string">"simulationType"</span>，</span><br><span class="line">    // 然后将<span class="string">"simulationType"</span>对应的值赋值给变量<span class="string">"modelType"</span>（对于单相流，modelType 只可能是 <span class="string">"RAS"</span> 或者 <span class="string">"LES"</span>）。</span><br><span class="line">    const word modelType</span><br><span class="line">    (</span><br><span class="line">        IOdictionary</span><br><span class="line">        (</span><br><span class="line">            IOobject</span><br><span class="line">            (</span><br><span class="line">                <span class="string">"turbulenceProperties"</span>,</span><br><span class="line">                U.time().constant(),</span><br><span class="line">                U.db(),</span><br><span class="line">                IOobject::MUST_READ_IF_MODIFIED,</span><br><span class="line">                IOobject::NO_WRITE,</span><br><span class="line">                false</span><br><span class="line">            )</span><br><span class="line">        ).lookup(<span class="string">"simulationType"</span>)</span><br><span class="line">    );</span><br><span class="line"></span><br><span class="line">    Info<span class="variable">&lt;&lt; "Selecting turbulence model type " &lt;&lt; modelType &lt;&lt; endl;</span><br><span class="line"></span><br><span class="line">    turbulenceModelConstructorTable::iterator cstrIter =</span><br><span class="line">        turbulenceModelConstructorTablePtr_-&gt;</span>find(modelType);</span><br><span class="line"></span><br><span class="line">    if (cstrIter == turbulenceModelConstructorTablePtr_-&gt;end())</span><br><span class="line">    &#123;</span><br><span class="line">        FatalErrorIn</span><br><span class="line">        (</span><br><span class="line">            <span class="string">"turbulenceModel::New(const volVectorField&amp;, "</span></span><br><span class="line">            <span class="string">"const surfaceScalarField&amp;, transportModel&amp;, const word&amp;)"</span></span><br><span class="line">        )   <span class="variable">&lt;&lt; "Unknown turbulenceModel type "</span><br><span class="line">            &lt;&lt; modelType &lt;&lt; nl &lt;&lt; nl</span><br><span class="line">            &lt;&lt; "Valid turbulenceModel types:" &lt;&lt; endl</span><br><span class="line">            &lt;&lt; turbulenceModelConstructorTablePtr_-&gt;</span>sortedToc()</span><br><span class="line">            <span class="variable">&lt;&lt; exit(FatalError);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    return autoPtr&lt;turbulenceModel&gt;</span></span><br><span class="line">    (</span><br><span class="line">        cstrIter()(U, phi, transport, turbulenceModelName)</span><br><span class="line">    );</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">// <span class="keyword">*</span> <span class="keyword">*</span> <span class="keyword">*</span> <span class="keyword">*</span> <span class="keyword">*</span> <span class="keyword">*</span> <span class="keyword">*</span> <span class="keyword">*</span> <span class="keyword">*</span> <span class="keyword">*</span> <span class="keyword">*</span> <span class="keyword">*</span> <span class="keyword">*</span> <span class="keyword">*</span> <span class="keyword">*</span> Member Functions  <span class="keyword">*</span> <span class="keyword">*</span> <span class="keyword">*</span> <span class="keyword">*</span> <span class="keyword">*</span> <span class="keyword">*</span> <span class="keyword">*</span> <span class="keyword">*</span> <span class="keyword">*</span> <span class="keyword">*</span> <span class="keyword">*</span> <span class="keyword">*</span> <span class="keyword">*</span> //</span><br><span class="line"></span><br><span class="line">void turbulenceModel::correct()</span><br><span class="line">&#123;</span><br><span class="line">    transportModel_.correct();</span><br><span class="line"></span><br><span class="line">    if (mesh_.changing())</span><br><span class="line">    &#123;</span><br><span class="line">        y_.correct();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line">// <span class="keyword">*</span> <span class="keyword">*</span> <span class="keyword">*</span> <span class="keyword">*</span> <span class="keyword">*</span> <span class="keyword">*</span> <span class="keyword">*</span> <span class="keyword">*</span> <span class="keyword">*</span> <span class="keyword">*</span> <span class="keyword">*</span> <span class="keyword">*</span> <span class="keyword">*</span> <span class="keyword">*</span> <span class="keyword">*</span> <span class="keyword">*</span> <span class="keyword">*</span> <span class="keyword">*</span> <span class="keyword">*</span> <span class="keyword">*</span> <span class="keyword">*</span> <span class="keyword">*</span> <span class="keyword">*</span> <span class="keyword">*</span> <span class="keyword">*</span> <span class="keyword">*</span> <span class="keyword">*</span> <span class="keyword">*</span> <span class="keyword">*</span> <span class="keyword">*</span> <span class="keyword">*</span> <span class="keyword">*</span> <span class="keyword">*</span> <span class="keyword">*</span> <span class="keyword">*</span> <span class="keyword">*</span> <span class="keyword">*</span> //</span><br><span class="line"></span><br><span class="line">&#125; // End namespace incompressible</span><br><span class="line">&#125; // End namespace Foam</span><br></pre></td></tr></table></figure></p>
<p>从基类 <code>turbulenceModel</code> 以下，就要花开两朵，各表一枝了。先来看 <code>RAS</code> 类的湍流模型。</p>
<h5 id="1-2_RAS_模型">1.2 RAS 模型</h5><p>我们从头文件 RASModel.H 看起<br><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br><span class="line">143</span><br><span class="line">144</span><br><span class="line">145</span><br><span class="line">146</span><br><span class="line">147</span><br><span class="line">148</span><br><span class="line">149</span><br><span class="line">150</span><br><span class="line">151</span><br><span class="line">152</span><br><span class="line">153</span><br><span class="line">154</span><br><span class="line">155</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">namespace</span> Foam</span><br><span class="line">&#123;</span><br><span class="line"><span class="keyword">namespace</span> incompressible</span><br><span class="line">&#123;</span><br><span class="line"></span><br><span class="line"><span class="comment">/*---------------------------------------------------------------------------*\</span><br><span class="line">                           Class RASModel Declaration</span><br><span class="line">\*---------------------------------------------------------------------------*/</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> RASModel</span><br><span class="line">:</span><br><span class="line">    <span class="keyword">public</span> turbulenceModel, <span class="comment">// RASModel 类是前面讲的turbulenceModel类的派生类</span></span><br><span class="line">    <span class="keyword">public</span> IOdictionary <span class="comment">// 同时也继承 IOdictionary 类</span></span><br><span class="line">&#123;</span><br><span class="line"></span><br><span class="line"><span class="keyword">protected</span>:</span><br><span class="line">    </span><br><span class="line">        <span class="comment">// 两个开关变量，类似于 C++ 中的bool变量，其值要么是true，要么是false。</span></span><br><span class="line">	<span class="comment">// 只是这里将 true 换成 on，false 换成 off 也是一样的。</span></span><br><span class="line">        Switch turbulence_;</span><br><span class="line">        Switch printCoeffs_;  </span><br><span class="line"></span><br><span class="line">        <span class="comment">//- Model coefficients dictionary</span></span><br><span class="line">        dictionary coeffDict_;</span><br><span class="line"></span><br><span class="line">        <span class="comment">//- Lower limit of k</span></span><br><span class="line">        dimensionedScalar kMin_;</span><br><span class="line"></span><br><span class="line">        <span class="comment">//- Lower limit of epsilon</span></span><br><span class="line">        dimensionedScalar epsilonMin_;</span><br><span class="line"></span><br><span class="line">        <span class="comment">//- Lower limit for omega</span></span><br><span class="line">        dimensionedScalar omegaMin_;</span><br><span class="line"></span><br><span class="line">    <span class="comment">// Protected Member Functions</span></span><br><span class="line"></span><br><span class="line">        <span class="comment">//- Print model coefficients</span></span><br><span class="line">        <span class="function"><span class="keyword">virtual</span> <span class="keyword">void</span> <span class="title">printCoeffs</span><span class="params">()</span></span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">private</span>:</span><br><span class="line">    <span class="comment">// Private Member Functions</span></span><br><span class="line">        <span class="comment">//- Disallow default bitwise copy construct</span></span><br><span class="line">        RASModel(<span class="keyword">const</span> RASModel&amp;);</span><br><span class="line">        <span class="comment">//- Disallow default bitwise assignment</span></span><br><span class="line">        <span class="keyword">void</span> <span class="keyword">operator</span>=(<span class="keyword">const</span> RASModel&amp;);</span><br><span class="line">        </span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line"></span><br><span class="line">    <span class="comment">//- Runtime type information</span></span><br><span class="line">    TypeName(<span class="string">"RASModel"</span>);</span><br><span class="line"></span><br><span class="line"><span class="comment">// 这里也涉及到 运行时选择机制，以后一起讲。</span></span><br><span class="line">        declareRunTimeSelectionTable</span><br><span class="line">        (</span><br><span class="line">            autoPtr,</span><br><span class="line">            RASModel,</span><br><span class="line">            dictionary,</span><br><span class="line">            (</span><br><span class="line">                <span class="keyword">const</span> volVectorField&amp; U,</span><br><span class="line">                <span class="keyword">const</span> surfaceScalarField&amp; phi,</span><br><span class="line">                transportModel&amp; transport,</span><br><span class="line">                <span class="keyword">const</span> word&amp; turbulenceModelName</span><br><span class="line">            ),</span><br><span class="line">            (U, phi, transport, turbulenceModelName)</span><br><span class="line">        );</span><br><span class="line"></span><br><span class="line">        <span class="comment">// 构造函数</span></span><br><span class="line">        RASModel</span><br><span class="line">        (</span><br><span class="line">            <span class="keyword">const</span> word&amp; type,</span><br><span class="line">            <span class="keyword">const</span> volVectorField&amp; U,</span><br><span class="line">            <span class="keyword">const</span> surfaceScalarField&amp; phi,</span><br><span class="line">            transportModel&amp; transport,</span><br><span class="line">            <span class="keyword">const</span> word&amp; turbulenceModelName = turbulenceModel::typeName</span><br><span class="line">        );</span><br><span class="line"></span><br><span class="line">        <span class="comment">//- Return a reference to the selected RAS model 这个函数作为运行时选择机制里的选择器。</span></span><br><span class="line">        <span class="keyword">static</span> autoPtr&lt;RASModel&gt; New</span><br><span class="line">        (</span><br><span class="line">            <span class="keyword">const</span> volVectorField&amp; U,</span><br><span class="line">            <span class="keyword">const</span> surfaceScalarField&amp; phi,</span><br><span class="line">            transportModel&amp; transport,</span><br><span class="line">            <span class="keyword">const</span> word&amp; turbulenceModelName = turbulenceModel::typeName</span><br><span class="line">        );</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">    <span class="comment">// Member Functions</span></span><br><span class="line"></span><br><span class="line">        <span class="comment">// Access</span></span><br><span class="line"></span><br><span class="line">            <span class="comment">// 注意，一下这些成员函数，是将来 RASModel 类的派生类们可能会用到的，这里一起定义了，</span></span><br><span class="line">	    <span class="comment">// 后面的派生类将可以直接继承这些函数，这样达到了代码重复利用的作用。</span></span><br><span class="line">            <span class="comment">//- Return the lower allowable limit for k (default: SMALL)</span></span><br><span class="line">            <span class="keyword">const</span> dimensionedScalar&amp; kMin() <span class="keyword">const</span></span><br><span class="line">            &#123;</span><br><span class="line">                <span class="keyword">return</span> kMin_;</span><br><span class="line">            &#125;</span><br><span class="line"></span><br><span class="line">            <span class="comment">//- Return the lower allowable limit for epsilon (default: SMALL)</span></span><br><span class="line">            <span class="keyword">const</span> dimensionedScalar&amp; epsilonMin() <span class="keyword">const</span></span><br><span class="line">            &#123;</span><br><span class="line">                <span class="keyword">return</span> epsilonMin_;</span><br><span class="line">            &#125;</span><br><span class="line"></span><br><span class="line">            <span class="comment">//- Return the lower allowable limit for omega (default: SMALL)</span></span><br><span class="line">            <span class="keyword">const</span> dimensionedScalar&amp; omegaMin() <span class="keyword">const</span></span><br><span class="line">            &#123;</span><br><span class="line">                <span class="keyword">return</span> omegaMin_;</span><br><span class="line">            &#125;</span><br><span class="line"></span><br><span class="line">            <span class="comment">//- Allow kMin to be changed</span></span><br><span class="line">            dimensionedScalar&amp; kMin()</span><br><span class="line">            &#123;</span><br><span class="line">                <span class="keyword">return</span> kMin_;</span><br><span class="line">            &#125;</span><br><span class="line"></span><br><span class="line">            <span class="comment">//- Allow epsilonMin to be changed</span></span><br><span class="line">            dimensionedScalar&amp; epsilonMin()</span><br><span class="line">            &#123;</span><br><span class="line">                <span class="keyword">return</span> epsilonMin_;</span><br><span class="line">            &#125;</span><br><span class="line"></span><br><span class="line">            <span class="comment">//- Allow omegaMin to be changed</span></span><br><span class="line">            dimensionedScalar&amp; omegaMin()</span><br><span class="line">            &#123;</span><br><span class="line">                <span class="keyword">return</span> omegaMin_;</span><br><span class="line">            &#125;</span><br><span class="line"></span><br><span class="line">            <span class="comment">//- Const access to the coefficients dictionary</span></span><br><span class="line">            <span class="keyword">virtual</span> <span class="keyword">const</span> dictionary&amp; coeffDict() <span class="keyword">const</span></span><br><span class="line">            &#123;</span><br><span class="line">                <span class="keyword">return</span> coeffDict_;</span><br><span class="line">            &#125;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">        <span class="comment">//- Return the effective viscosity</span></span><br><span class="line">	<span class="comment">// 这个函数很重要，默认情况下，雷诺时均湍流模型中，有效粘度等于湍流粘度加层流粘度，即nut + nu。</span></span><br><span class="line">	<span class="comment">// 这里的 nut 和 nu 两个函数在基类 turbulenceModel 声明了，请往前翻以证实这一点。</span></span><br><span class="line">        <span class="keyword">virtual</span> tmp&lt;volScalarField&gt; nuEff() <span class="keyword">const</span> </span><br><span class="line">        &#123;</span><br><span class="line">            <span class="keyword">return</span> tmp&lt;volScalarField&gt;</span><br><span class="line">            (</span><br><span class="line">                <span class="keyword">new</span> volScalarField(<span class="string">"nuEff"</span>, nut() + nu())</span><br><span class="line">            );</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">        <span class="comment">//- Solve the turbulence equations and correct the turbulence viscosity</span></span><br><span class="line">        <span class="function"><span class="keyword">virtual</span> <span class="keyword">void</span> <span class="title">correct</span><span class="params">()</span></span>;</span><br><span class="line"></span><br><span class="line">        <span class="comment">//- Read RASProperties dictionary</span></span><br><span class="line">        <span class="function"><span class="keyword">virtual</span> <span class="keyword">bool</span> <span class="title">read</span><span class="params">()</span></span>;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line">&#125; <span class="comment">// End namespace incompressible</span></span><br><span class="line">&#125; <span class="comment">// End namespace Foam</span></span><br></pre></td></tr></table></figure></p>
<p>再来看 <code>RASModel.C</code>，这里跟 <code>turbulenceModel.C</code> 类似，重点关注构造函数和 选择器（Selector）函数。<br><figure class="highlight aspectj"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br><span class="line">143</span><br><span class="line">144</span><br><span class="line">145</span><br><span class="line">146</span><br><span class="line">147</span><br><span class="line">148</span><br><span class="line">149</span><br><span class="line">150</span><br><span class="line">151</span><br><span class="line">152</span><br><span class="line">153</span><br><span class="line">154</span><br><span class="line">155</span><br><span class="line">156</span><br><span class="line">157</span><br><span class="line">158</span><br><span class="line">159</span><br><span class="line">160</span><br><span class="line">161</span><br><span class="line">162</span><br><span class="line">163</span><br><span class="line">164</span><br><span class="line">165</span><br><span class="line">166</span><br><span class="line">167</span><br><span class="line">168</span><br><span class="line">169</span><br><span class="line">170</span><br><span class="line">171</span><br><span class="line">172</span><br><span class="line">173</span><br><span class="line">174</span><br><span class="line">175</span><br><span class="line">176</span><br><span class="line">177</span><br></pre></td><td class="code"><pre><span class="line">namespace Foam</span><br><span class="line">&#123;</span><br><span class="line">namespace incompressible</span><br><span class="line">&#123;</span><br><span class="line"></span><br><span class="line">defineTypeNameAndDebug(RASModel, <span class="number">0</span>);</span><br><span class="line">defineRunTimeSelectionTable(RASModel, dictionary);</span><br><span class="line">addToRunTimeSelectionTable(turbulenceModel, RASModel, turbulenceModel);</span><br><span class="line"></span><br><span class="line"><span class="comment">// * * * * * * * * * * * * * Protected Member Functions  * * * * * * * * * * //</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">void</span> RASModel::printCoeffs()</span><br><span class="line">&#123;</span><br><span class="line">    <span class="keyword">if</span> (printCoeffs_)</span><br><span class="line">    &#123;</span><br><span class="line">        Info&lt;&lt; type() &lt;&lt; <span class="string">"Coeffs"</span> &lt;&lt; coeffDict_ &lt;&lt; endl;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 构造函数</span></span><br><span class="line">RASModel::RASModel</span><br><span class="line">(</span><br><span class="line">    <span class="keyword">const</span> word&amp; type,</span><br><span class="line">    <span class="keyword">const</span> volVectorField&amp; U,</span><br><span class="line">    <span class="keyword">const</span> surfaceScalarField&amp; phi,</span><br><span class="line">    transportModel&amp; transport,</span><br><span class="line">    <span class="keyword">const</span> word&amp; turbulenceModelName</span><br><span class="line">)</span><br><span class="line">:</span><br><span class="line">类似的，这里也是使用成员初始化列表来初始化当前类及其父类的数据成员</span><br><span class="line"></span><br><span class="line">    // 这一句是传递参数给父类 turbulenceModel，注意这里传给父类构造函数的参数要与父类中的构造函数的参数表一致哦</span><br><span class="line">    turbulenceModel(U, phi, transport, turbulenceModelName), </span><br><span class="line">    </span><br><span class="line"> //这里是建立一个IOobject来初始化另一个父类IOdictionary，注意这里建立的是一个名为“RASProperties”的IO对象，这个文件相信用过 OpenFOAM 湍流模拟的一定很熟悉吧</span><br><span class="line">    IOdictionary</span><br><span class="line">    (</span><br><span class="line">        IOobject</span><br><span class="line">        (</span><br><span class="line">            <span class="string">"RASProperties"</span>,</span><br><span class="line">            U.time().constant(), // 这里表示文件的位置是在constant文件夹下</span><br><span class="line">            U.db(),</span><br><span class="line">            IOobject::MUST_READ_IF_MODIFIED, //这里的意思是，如果修改了，则需要重新读取，所以，如果你在算例运行时修改了这个文件，你的修改会即时生效的</span><br><span class="line">            IOobject::NO_WRITE</span><br><span class="line">        )</span><br><span class="line">    ),</span><br><span class="line">    </span><br><span class="line">  // 查找“turbulence” 关键字，并用其对应的值来初始化变量“turbulnce_”。</span><br><span class="line">    turbulence_(lookup(<span class="string">"turbulence"</span>)),</span><br><span class="line">    // 同上，区别是这里是带缺省参数的，也就是说如果找不到“printCoeffs” 就用缺省值“<span class="keyword">false</span>”</span><br><span class="line">    printCoeffs_(lookupOrDefault&lt;Switch&gt;(<span class="string">"printCoeffs"</span>, <span class="keyword">false</span>)), </span><br><span class="line">    </span><br><span class="line">    // 这里是读取模型参数字典来初始化变量“coeffDict_”。注意，这里的 type 是啥？这个要等到进一步看一个具体的湍流模型类时才能明了。 </span><br><span class="line">    // 另外，注意这里的 `lookup` ， `lookupOrDefault` 和 `subOrEmptyDict` 三个函数都是继承自 IOdictionary 类的函数。</span><br><span class="line">    coeffDict_(subOrEmptyDict(type + <span class="string">"Coeffs"</span>)), </span><br><span class="line"></span><br><span class="line">    kMin_(<span class="string">"kMin"</span>, sqr(dimVelocity), SMALL),</span><br><span class="line">    epsilonMin_(<span class="string">"epsilonMin"</span>, kMin_.dimensions()/dimTime, SMALL),</span><br><span class="line">    omegaMin_(<span class="string">"omegaMin"</span>, dimless/dimTime, SMALL)</span><br><span class="line">&#123;</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 这里是从 RASProperties 里读取kMin等的值，注意如果 RASProperties 里不设置那就使用上面初始化的值“SMALL”。</span></span><br><span class="line">    <span class="comment">// 注意这里的“*this”代表的是 RASModel 类本身，但是readIfPresent函数的参数应该是 dictionary 类，由于RASModel 类继承自 IODictionary 类，所以，这里其实隐含了一个派生类指针向基类指针的转换</span></span><br><span class="line">    kMin_.readIfPresent(*<span class="keyword">this</span>);  </span><br><span class="line">    epsilonMin_.readIfPresent(*<span class="keyword">this</span>);</span><br><span class="line">    omegaMin_.readIfPresent(*<span class="keyword">this</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// Force the construction of the mesh deltaCoeffs which may be needed</span></span><br><span class="line">    <span class="comment">// for the construction of the derived models and BCs</span></span><br><span class="line">    mesh_.deltaCoeffs();</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment">//这个也是跟运行时选择有关，以后会细说</span></span><br><span class="line">autoPtr&lt;RASModel&gt; RASModel::New</span><br><span class="line">(</span><br><span class="line">    <span class="keyword">const</span> volVectorField&amp; U,</span><br><span class="line">    <span class="keyword">const</span> surfaceScalarField&amp; phi,</span><br><span class="line">    transportModel&amp; transport,</span><br><span class="line">    <span class="keyword">const</span> word&amp; turbulenceModelName</span><br><span class="line">)</span><br><span class="line">&#123;</span><br><span class="line">    <span class="comment">// get model name, but do not register the dictionary</span></span><br><span class="line">    <span class="comment">// otherwise it is registered in the database twice</span></span><br><span class="line">    <span class="keyword">const</span> word modelType</span><br><span class="line">    (</span><br><span class="line">        IOdictionary</span><br><span class="line">        (</span><br><span class="line">            IOobject</span><br><span class="line">            (</span><br><span class="line">                <span class="string">"RASProperties"</span>,</span><br><span class="line">                U.time().constant(),</span><br><span class="line">                U.db(),</span><br><span class="line">                IOobject::MUST_READ_IF_MODIFIED,</span><br><span class="line">                IOobject::NO_WRITE,</span><br><span class="line">                <span class="keyword">false</span></span><br><span class="line">            )</span><br><span class="line">        ).lookup(<span class="string">"RASModel"</span>)</span><br><span class="line">    );</span><br><span class="line"></span><br><span class="line">    Info&lt;&lt; <span class="string">"Selecting RAS turbulence model "</span> &lt;&lt; modelType &lt;&lt; endl;</span><br><span class="line"></span><br><span class="line">    dictionaryConstructorTable::iterator cstrIter =</span><br><span class="line">        dictionaryConstructorTablePtr_-&gt;find(modelType);</span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> (cstrIter == dictionaryConstructorTablePtr_-&gt;end())</span><br><span class="line">    &#123;</span><br><span class="line">        FatalErrorIn</span><br><span class="line">        (</span><br><span class="line">            <span class="string">"RASModel::New"</span></span><br><span class="line">            <span class="string">"("</span></span><br><span class="line">                <span class="string">"const volVectorField&amp;, "</span></span><br><span class="line">                <span class="string">"const surfaceScalarField&amp;, "</span></span><br><span class="line">                <span class="string">"transportModel&amp;, "</span></span><br><span class="line">                <span class="string">"const word&amp;"</span></span><br><span class="line">            <span class="string">")"</span></span><br><span class="line">        )   &lt;&lt; <span class="string">"Unknown RASModel type "</span></span><br><span class="line">            &lt;&lt; modelType &lt;&lt; nl &lt;&lt; nl</span><br><span class="line">            &lt;&lt; <span class="string">"Valid RASModel types:"</span> &lt;&lt; endl</span><br><span class="line">            &lt;&lt; dictionaryConstructorTablePtr_-&gt;sortedToc()</span><br><span class="line">            &lt;&lt; exit(FatalError);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">return</span> autoPtr&lt;RASModel&gt;</span><br><span class="line">    (</span><br><span class="line">        cstrIter()(U, phi, transport, turbulenceModelName)</span><br><span class="line">    );</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment">// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">void</span> RASModel::correct()</span><br><span class="line">&#123;</span><br><span class="line">    turbulenceModel::correct();</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">bool RASModel::read()</span><br><span class="line">&#123;</span><br><span class="line">    <span class="comment">//if (regIOobject::read())</span></span><br><span class="line"></span><br><span class="line">    <span class="comment">// Bit of trickery : we are both IOdictionary ('RASProperties') and</span></span><br><span class="line">    <span class="comment">// an regIOobject from the turbulenceModel level. Problem is to distinguish</span></span><br><span class="line">    <span class="comment">// between the two - we only want to reread the IOdictionary.</span></span><br><span class="line"></span><br><span class="line">    bool ok = IOdictionary::readData</span><br><span class="line">    (</span><br><span class="line">        IOdictionary::readStream</span><br><span class="line">        (</span><br><span class="line">            IOdictionary::type()</span><br><span class="line">        )</span><br><span class="line">    );</span><br><span class="line">    IOdictionary::close();</span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> (ok)</span><br><span class="line">    &#123;</span><br><span class="line">        lookup(<span class="string">"turbulence"</span>) &gt;&gt; turbulence_;</span><br><span class="line"></span><br><span class="line">        <span class="keyword">if</span> (<span class="keyword">const</span> dictionary* dictPtr = subDictPtr(type() + <span class="string">"Coeffs"</span>))</span><br><span class="line">        &#123;</span><br><span class="line">            coeffDict_ &lt;&lt;= *dictPtr;</span><br><span class="line">        &#125;</span><br><span class="line">        kMin_.readIfPresent(*<span class="keyword">this</span>);</span><br><span class="line">        epsilonMin_.readIfPresent(*<span class="keyword">this</span>);</span><br><span class="line">        omegaMin_.readIfPresent(*<span class="keyword">this</span>);</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">true</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">else</span></span><br><span class="line">    &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">false</span>;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //</span></span><br><span class="line"></span><br><span class="line">&#125; <span class="comment">// End namespace incompressible</span></span><br><span class="line">&#125; <span class="comment">// End namespace Foam</span></span><br></pre></td></tr></table></figure></p>
<h5 id="1-3_LES_模型">1.3 LES 模型</h5><p>LESModel 类的结构与 RASModel 非常接近，所以这里就简单提一下区别之处。</p>
<ul>
<li>delta_ 成员<figure class="highlight css"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">autoPtr</span>&lt;<span class="rule"><span class="attribute">Foam</span>:<span class="value">:LESdelta&gt; delta_</span></span>;</span><br></pre></td></tr></table></figure>
</li>
</ul>
<p>这个成员是 LESdelta 类的对象，定义滤波尺度。这个类的定义在 <code>src/turbulenceModels/LES/LESdeltas</code> ，当中定义了几个可选的 delta 模型</p>
<ul>
<li>亚格子粘度和应力</li>
</ul>
<figure class="highlight cs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//- Return the SGS viscosity. 亚格子粘度</span></span><br><span class="line">       <span class="function"><span class="keyword">virtual</span> tmp&lt;volScalarField&gt; <span class="title">nuSgs</span><span class="params">()</span> <span class="keyword">const</span> </span>= <span class="number">0</span>;</span><br><span class="line"></span><br><span class="line">       <span class="comment">//- Return the effective viscosity</span></span><br><span class="line">       <span class="function"><span class="keyword">virtual</span> tmp&lt;volScalarField&gt; <span class="title">nuEff</span><span class="params">()</span> <span class="keyword">const</span> <span class="comment">//有效粘度等于亚格子粘度与分子粘度之和</span></span><br><span class="line">       </span>&#123;</span><br><span class="line">           <span class="keyword">return</span> tmp&lt;volScalarField&gt;</span><br><span class="line">           (</span><br><span class="line">               <span class="keyword">new</span> volScalarField(<span class="string">"nuEff"</span>, nuSgs() + nu())</span><br><span class="line">           );</span><br><span class="line">       &#125;</span><br><span class="line">       </span><br><span class="line">       <span class="comment">//- Return the sub-grid stress tensor. // 亚格子应力</span></span><br><span class="line">       <span class="function"><span class="keyword">virtual</span> tmp&lt;volSymmTensorField&gt; <span class="title">B</span><span class="params">()</span> <span class="keyword">const</span> </span>= <span class="number">0</span>;</span><br></pre></td></tr></table></figure>
<p>LESModel.C 的结构与 RASModel.C 几乎一样，所以这里就不重复了。</p>
<p>前面提到，基类 turbulenceModel 里声明了很多纯虚函数，所以，turbulenceModel 类是抽象类，不能直接创建对象。注意这里的 RASModel 类和 LESModel 类由于继承了 turbulenceModel 类的纯虚函数，所以这两个依然是抽象类。这一点在后面解析具体湍流模型类的时候还会提到，这里先提个醒。</p>
<h5 id="1-4_继承派生关系">1.4 继承派生关系</h5><p>前面看完了基类 turbulenceModel，RASModel 以及 LESModel，可以看出这三个类的继承派生关系为：</p>
<p><img src="/image/turbulenceModel/RAS_LES.png" alt="RAS 和 LES 与 turbulenceModel 的继承关系"></p>
<p>下面继续看具体湍流模型类与基类的继承关系。<br>先看雷诺时均类湍流模型：<br>位于 <code>src/turbulenceModels/incompressible/RAS</code> 目录下的都是雷诺时均类的湍流模型，这个类型的继承关系很简单：所有具体湍流模型类都继承自 RASModel 类，关系示意图如下：</p>
<p><img src="/image/turbulenceModel/RAS.png" alt="RAS 类湍流模型的继承关系"></p>
<p>位于 <code>src/turbulenceModels/incompressible/LES</code> 目录下的是大涡模拟类型的湍流模型，这类湍流模型的继承关系比雷诺时均类的要复杂一点，但是也不难捋清，过程我就不详述了，下面给出我整理的继承关系图：</p>
<p><img src="/image/turbulenceModel/LES.png" alt="LES 类湍流模型的继承关系"></p>
<p>上图中，虚线框里的是抽象类，实线框里的是具体的可以调用的湍流模型类。</p>
<h5 id="1-5_求解器中湍流模型的调用">1.5 求解器中湍流模型的调用</h5><p>最后简单提一下求解器中调用湍流模型的接口。以 <code>pisoFoam</code> 求解器为例：<br>纵观 <code>pisoFoam</code> 的代码，跟湍流模型有关的共有三处，第一处是在 createField.H 的最后面，创建一个智能指针<br><figure class="highlight css"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">autoPtr</span>&lt;<span class="rule"><span class="attribute">incompressible</span>:<span class="value">:turbulenceModel&gt; turbulence</span><br><span class="line">    (</span><br><span class="line">        incompressible::turbulenceModel::<span class="function">New</span>(U, phi, laminarTransport)</span><br><span class="line">    )</span></span>;</span><br></pre></td></tr></table></figure></p>
<p>注意，这个指针的类型是 <code>incompressible::turbulenceModel</code> ，也就是说，创建的是基类的指针。<br>第二处位于 <code>UEqn</code> 中，<br><figure class="highlight stylus"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">+ turbulence-&gt;<span class="function"><span class="title">divDevReff</span><span class="params">(U)</span></span></span><br></pre></td></tr></table></figure></p>
<p>从这里可以看出，这是用指针 <code>turbulence</code> 调用成员函数 <code>divDevReff</code><br>第三处在压力修正之后<br><figure class="highlight ocaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">turbulence-&gt;correct<span class="literal">()</span>;</span><br></pre></td></tr></table></figure></p>
<p>这里是调用成员函数 <code>correct</code> 。<br>这简单的几行代码，就完成了湍流模型的调用。这里先大致说一下调用的原理和过程，详细的留待后面跟运行时选择机制一起说。<br>首先，注意刚才提到的智能指针 <code>turbulence</code> 的类型是 <code>incompressible::turbulenceModel</code> ，是基类类型的。这里就不得不说一下 C++ <strong>虚函数</strong>的作用了。还记得上面提到的基类 <code>turbulenceModel</code> 中声明的那些<strong>纯虚函数</strong>吧，如果你往上翻翻，你会发现， <code>divDevReff</code> 和 <code>correct</code> 在基类 <code>turbulenceModel</code> 中都被声明为<strong>纯虚函数</strong>。这里只要把握两点，就能理解湍流模型的调用原理：</p>
<ol>
<li>基类类型的指针可以指向派生类的对象；</li>
<li>在基类中声明的纯虚函数可以在派生类中进行定义，当基类类型指针指向派生类对象以后，用这个指针调用成员函数时，实际调用的是指针指向的派生类中定义的函数。</li>
</ol>
<p>把握这两点，然后再去理解湍流模型的调用过程：<br>首先是调用 <code>incompressible::turbulenceModel::New</code> 函数来初始化指针 <code>turbulence</code> ，查看上面 <code>turbulenceModel</code> 类中 <code>New</code> 函数的定义，可以知道，函数要先从“turbulenceProperties” 文件里 <code>simulationType</code>　关键字，从而决定是调用 <code>RAS</code> 模型还是 <code>LES</code> 模型。如果用户设定的是 <code>RAS</code> ，那么 <code>turbulenceModel</code> 类的 <code>New</code> 函数将返回一个指向 <code>RASModel</code> 类的指针，这个指针将继续调用 <code>RASModel</code> 类的 <code>New</code> 函数，并在这个函数中读取 <code>RASProperties</code> 文件，查找关键字 <code>RASModel</code> ，从而决定具体调用的湍流模型。假设用户指定的是 <code>kEpsilon</code> 那么最终 createField.H 中定义的指针 <code>turbulence</code> 将指向一个 <code>kEpsilon</code> 类的对象，由此， <code>turbulence-&gt;divDevReff(U)</code> 和 <code>turbulence-&gt;correct()</code> 都将分别调用定义在 <code>kEpsilon</code> 类中的成员函数 <code>divDevReff</code> 和 <code>correct</code>。<br>一个简单的湍流模型调用示意图如下：</p>
<p><img src="/image/turbulenceModel/call.png" alt="湍流模型调用示意图"></p>
<p>以上是 RAS 类型模型的调用，LES 类型的基本上差不多，但是，从上面的继承关系图也能看出，LES 模型类的结构更复杂一点。根本原因在于，LES 模型不像 RAS 模型那样都是同一的对湍流粘度 <code>nut</code> 建模，而是有一部分是对亚格子粘度 <code>nuSgs</code> 建模（这一部分湍流模型均继承自 <code>GenEddyVisc</code> ），还有另一部分是直接对亚格子应力 <code>B</code> 建模（这一部分湍流模型均继承自 <code>GenSGSStress</code> ），此外，分离涡模型（Detached eddy model， DESModel）也放在这个目录下，而且还有一个直接继承自 <code>LESModel</code> 的模型 <code>kOmegaSSTSAS</code> （这个模型与 <code>LESModel</code> 的关系就跟 <code>kEpsilon</code> 与 <code>RASModel</code> 的关系一样）。虽然有这么多种类型，但是调用过程其实跟 RAS 类型的是差不多的。如果从字典文件“turbulenceProperties” 里读到的 <code>simulationType</code> 是 <code>LES</code> 的话，那么将继续从字典文件 <code>LESProperties</code> 里读取具体的 LES 模型。上面总结的那张继承关系图中，所有的实线框中的模型都可以选择。但是，具体的模型需要具体的设置，比如，需要设置滤波尺度 <code>delta</code> 模型，还可能需要设置 <code>filter</code> 模型，具体的要求可以去具体的湍流模型类的代码中去看。如果你了解一点你需要使用的湍流模型的基本理论，能写出模型的方程，那要看懂这个湍流模型在 OpenFOAM 中实现的代码是很容易的。</p>
<p>上述关于调用过程的叙述，只是我的理解，其实不严谨，但大致原理应该是这样。计划中这个系列将写三篇，我将在第三篇中叙述运行时选择机制，到时候还会深入说说这个调用过程。</p>
<p>P.S：本系列在筹划时，OpenFOAM-3.0 版本还没发布。随着 3.0 版本的发布，本系列里对湍流模型的描述已经“过时”了，因为在 3.0 版中，湍流模型类进行了重新模板化，将单相湍流和多相湍流模型整合在一起了，所以这里的描述只适用于 3.0 以下的版本。</p>

      
    </div>
    <footer class="article-footer">
      <a data-url="http://xiaopingqiu.github.io/2015/11/25/OpenFOAM-singlePhase-turbulenceModel/" data-id="cj2lay36v005okkmbwpf81ogk" class="article-share-link">Share</a>
      
      
  <ul class="article-tag-list"><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/Code-Explained/">Code Explained</a></li><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/turbulence-model/">turbulence model</a></li></ul>

    </footer>
  </div>
  
    
<nav id="article-nav">
  
    <a href="/2015/11/25/swak4Foam-alpha-water/" id="article-nav-newer" class="article-nav-link-wrap">
      <strong class="article-nav-caption">Newer</strong>
      <div class="article-nav-title">
        
          swak4Foam 如何用于名字形如 alpha.water 的场？
        
      </div>
    </a>
  
  
    <a href="/2015/10/06/blockMesh-multi-sectional-grading/" id="article-nav-older" class="article-nav-link-wrap">
      <strong class="article-nav-caption">Older</strong>
      <div class="article-nav-title">blockMesh 的新功能：multi/sectional grading in a block</div>
    </a>
  
</nav>

  
</article>


<section id="comments">
  <!-- 多说评论框 start -->
  <div class="ds-thread" data-thread-key="post-OpenFOAM-singlePhase-turbulenceModel" data-title="OpenFOAM 中的单相流湍流模型之一" data-url="http://xiaopingqiu.github.io/2015/11/25/OpenFOAM-singlePhase-turbulenceModel/"></div>
  <!-- 多说评论框 end -->
  <!-- 多说公共JS代码 start (一个网页只需插入一次) -->
  <script type="text/javascript">
  var duoshuoQuery = {short_name:"xiaopingqiu"};
	(function() {
		var ds = document.createElement('script');
		ds.type = 'text/javascript';ds.async = true;
		ds.src = (document.location.protocol == 'https:' ? 'https:' : 'http:') + '//static.duoshuo.com/embed.js';
		ds.charset = 'UTF-8';
		(document.getElementsByTagName('head')[0] 
		 || document.getElementsByTagName('body')[0]).appendChild(ds);
	})();
	</script>
  <!-- 多说公共JS代码 end -->
</section>

</section>
        
          <aside id="sidebar">
  
    
  <div class="widget-wrap">
    <h3 class="widget-title">Categories</h3>
    <div class="widget">
      <ul class="category-list"><li class="category-list-item"><a class="category-list-link" href="/categories/C/">C++</a><span class="category-list-count">2</span></li><li class="category-list-item"><a class="category-list-link" href="/categories/DEM/">DEM</a><span class="category-list-count">1</span></li><li class="category-list-item"><a class="category-list-link" href="/categories/OpenFOAM/">OpenFOAM</a><span class="category-list-count">44</span></li><li class="category-list-item"><a class="category-list-link" href="/categories/Paraview/">Paraview</a><span class="category-list-count">5</span></li><li class="category-list-item"><a class="category-list-link" href="/categories/swak4Foam/">swak4Foam</a><span class="category-list-count">1</span></li><li class="category-list-item"><a class="category-list-link" href="/categories/test/">test</a><span class="category-list-count">2</span></li><li class="category-list-item"><a class="category-list-link" href="/categories/vim/">vim</a><span class="category-list-count">1</span></li></ul>
    </div>
  </div>

  
    
  <div class="widget-wrap">
    <h3 class="widget-title">Tags</h3>
    <div class="widget">
      <ul class="tag-list"><li class="tag-list-item"><a class="tag-list-link" href="/tags/Boundary-conditions/">Boundary conditions</a><span class="tag-list-count">6</span></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/C/">C++</a><span class="tag-list-count">2</span></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/CentOS/">CentOS</a><span class="tag-list-count">1</span></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/Code-Explained/">Code Explained</a><span class="tag-list-count">29</span></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/LES/">LES</a><span class="tag-list-count">1</span></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/LIGGGHTS/">LIGGGHTS</a><span class="tag-list-count">1</span></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/ODE/">ODE</a><span class="tag-list-count">1</span></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/OpenFOAM/">OpenFOAM</a><span class="tag-list-count">20</span></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/Postprocessing/">Postprocessing</a><span class="tag-list-count">9</span></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/Preprocessing/">Preprocessing</a><span class="tag-list-count">2</span></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/RTS/">RTS</a><span class="tag-list-count">3</span></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/TIL/">TIL</a><span class="tag-list-count">1</span></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/Windows/">Windows</a><span class="tag-list-count">1</span></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/fvOptions/">fvOptions</a><span class="tag-list-count">2</span></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/groovyBC/">groovyBC</a><span class="tag-list-count">1</span></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/paraview/">paraview</a><span class="tag-list-count">1</span></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/test/">test</a><span class="tag-list-count">2</span></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/thermophysicalModels/">thermophysicalModels</a><span class="tag-list-count">5</span></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/turbulence-model/">turbulence model</a><span class="tag-list-count">7</span></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/vim/">vim</a><span class="tag-list-count">1</span></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/wall-functions/">wall functions</a><span class="tag-list-count">4</span></li></ul>
    </div>
  </div>

  
    
  <div class="widget-wrap">
    <h3 class="widget-title">Tag Cloud</h3>
    <div class="widget tagcloud">
      <a href="/tags/Boundary-conditions/" style="font-size: 15.56px;">Boundary conditions</a><a href="/tags/C/" style="font-size: 11.11px;">C++</a><a href="/tags/CentOS/" style="font-size: 10px;">CentOS</a><a href="/tags/Code-Explained/" style="font-size: 20px;">Code Explained</a><a href="/tags/LES/" style="font-size: 10px;">LES</a><a href="/tags/LIGGGHTS/" style="font-size: 10px;">LIGGGHTS</a><a href="/tags/ODE/" style="font-size: 10px;">ODE</a><a href="/tags/OpenFOAM/" style="font-size: 18.89px;">OpenFOAM</a><a href="/tags/Postprocessing/" style="font-size: 17.78px;">Postprocessing</a><a href="/tags/Preprocessing/" style="font-size: 11.11px;">Preprocessing</a><a href="/tags/RTS/" style="font-size: 12.22px;">RTS</a><a href="/tags/TIL/" style="font-size: 10px;">TIL</a><a href="/tags/Windows/" style="font-size: 10px;">Windows</a><a href="/tags/fvOptions/" style="font-size: 11.11px;">fvOptions</a><a href="/tags/groovyBC/" style="font-size: 10px;">groovyBC</a><a href="/tags/paraview/" style="font-size: 10px;">paraview</a><a href="/tags/test/" style="font-size: 11.11px;">test</a><a href="/tags/thermophysicalModels/" style="font-size: 14.44px;">thermophysicalModels</a><a href="/tags/turbulence-model/" style="font-size: 16.67px;">turbulence model</a><a href="/tags/vim/" style="font-size: 10px;">vim</a><a href="/tags/wall-functions/" style="font-size: 13.33px;">wall functions</a>
    </div>
  </div>

  
    
  <div class="widget-wrap">
    <h3 class="widget-title">Archives</h3>
    <div class="widget">
      <ul class="archive-list"><li class="archive-list-item"><a class="archive-list-link" href="/archives/2017/05/">五月 2017</a><span class="archive-list-count">1</span></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2016/08/">八月 2016</a><span class="archive-list-count">8</span></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2016/06/">六月 2016</a><span class="archive-list-count">5</span></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2016/05/">五月 2016</a><span class="archive-list-count">3</span></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2016/04/">四月 2016</a><span class="archive-list-count">12</span></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2016/03/">三月 2016</a><span class="archive-list-count">6</span></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2015/12/">十二月 2015</a><span class="archive-list-count">1</span></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2015/11/">十一月 2015</a><span class="archive-list-count">2</span></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2015/10/">十月 2015</a><span class="archive-list-count">1</span></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2015/09/">九月 2015</a><span class="archive-list-count">6</span></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2015/08/">八月 2015</a><span class="archive-list-count">1</span></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2015/06/">六月 2015</a><span class="archive-list-count">2</span></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2015/05/">五月 2015</a><span class="archive-list-count">6</span></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2015/04/">四月 2015</a><span class="archive-list-count">2</span></li></ul>
    </div>
  </div>

  
    
  <div class="widget-wrap">
    <h3 class="widget-title">Recents</h3>
    <div class="widget">
      <ul>
        
          <li>
            <a href="/2017/05/12/duoshuoAnnouncement/">多说评论系统将停止提供服务</a>
          </li>
        
          <li>
            <a href="/2016/08/27/ParaviewScritps/">Paraview 脚本一例</a>
          </li>
        
          <li>
            <a href="/2016/08/27/ParaviewCamera/">Paraview 中有关 Camera 的操作两例</a>
          </li>
        
          <li>
            <a href="/2016/08/27/ParaviewCustomFilter/">Paraview 中创建 Custom Filter</a>
          </li>
        
          <li>
            <a href="/2016/08/27/ParaviewStreamLineOnSlice/">在 Paraview 中画截面上的流线</a>
          </li>
        
      </ul>
    </div>
  </div>

  
</aside>
        
      </div>
      <footer id="footer">
  
  <div class="outer">
    <div id="footer-info" class="inner">
      &copy; 2017 Giskard Q.<br>
      Powered by <a href="http://hexo.io/" target="_blank">Hexo</a>
    </div>
  </div>
</footer>

<script src="//dn-lbstatics.qbox.me/lbservice/busuanzi/2.0/busuanzi.mini.js"/></script>

    </div>
    <nav id="mobile-nav">
  
    <a href="/" class="mobile-nav-link">Home</a>
  
    <a href="/archives" class="mobile-nav-link">Archives</a>
  
    <a href="/atom.xml" class="mobile-nav-link">Rss</a>
  
    <a href="/about" class="mobile-nav-link">About</a>
  
</nav>
    

<script src="//ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script>


  <link rel="stylesheet" href="/fancybox/jquery.fancybox.css" type="text/css">
  <script src="/fancybox/jquery.fancybox.pack.js" type="text/javascript"></script>


<script src="/js/script.js" type="text/javascript"></script>

<script>
  (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
  (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
  m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
  })(window,document,'script','//www.google-analytics.com/analytics.js','ga');

  ga('create', 'UA-62501686-1', 'auto');
  ga('send', 'pageview');

</script>

  </div>
<!-- mathjax config similar to math.stackexchange -->

<script type="text/x-mathjax-config">
  MathJax.Hub.Config({
    tex2jax: {
      inlineMath: [ ['$','$'], ["\\(","\\)"] ],
      processEscapes: true
    }
  });
</script>

<script type="text/x-mathjax-config">
    MathJax.Hub.Config({
      tex2jax: {
        skipTags: ['script', 'noscript', 'style', 'textarea', 'pre', 'code']
      }
    });
</script>

<script type="text/x-mathjax-config">
    MathJax.Hub.Queue(function() {
        var all = MathJax.Hub.getAllJax(), i;
        for(i=0; i < all.length; i += 1) {
            all[i].SourceElement().parentNode.className += ' has-jax';
        }
    });
</script>

<script type="text/javascript" src="http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML">
</script>
</body>
</html>